package com.yth.utils.ql.op;

import com.ql.util.express.Operator;

import java.util.Arrays;
import java.util.stream.IntStream;

/**
 * 数组流操作符工厂类，为每种数组类型提供专门的stream操作符实现
 *
 * @author yutianhong
 * @version 1.0
 * @since 2025/5/16 10:49
 */
public class ArrayStreamOperatorFactory {

    /**
     * 对象数组流操作符
     */
    public static Operator createObjectArrayStreamOperator() {
        return new ObjectArrayStreamOperator();
    }

    /**
     * int数组流操作符
     */
    public static Operator createIntArrayStreamOperator() {
        return new IntArrayStreamOperator();
    }

    /**
     * long数组流操作符
     */
    public static Operator createLongArrayStreamOperator() {
        return new LongArrayStreamOperator();
    }

    /**
     * double数组流操作符
     */
    public static Operator createDoubleArrayStreamOperator() {
        return new DoubleArrayStreamOperator();
    }

    /**
     * byte数组流操作符
     */
    public static Operator createByteArrayStreamOperator() {
        return new ByteArrayStreamOperator();
    }

    /**
     * boolean数组流操作符
     */
    public static Operator createBooleanArrayStreamOperator() {
        return new BooleanArrayStreamOperator();
    }

    /**
     * short数组流操作符
     */
    public static Operator createShortArrayStreamOperator() {
        return new ShortArrayStreamOperator();
    }

    /**
     * char数组流操作符
     */
    public static Operator createCharArrayStreamOperator() {
        return new CharArrayStreamOperator();
    }

    /**
     * float数组流操作符
     */
    public static Operator createFloatArrayStreamOperator() {
        return new FloatArrayStreamOperator();
    }

    private static class ObjectArrayStreamOperator extends Operator {
        @Override
        public Object executeInner(Object[] list) throws Exception {
            Object[] array = (Object[]) list[0];
            return Arrays.stream(array);
        }
    }

    private static class IntArrayStreamOperator extends Operator {
        @Override
        public Object executeInner(Object[] list) throws Exception {
            int[] array = (int[]) list[0];
            return Arrays.stream(array).boxed();
        }
    }

    private static class LongArrayStreamOperator extends Operator {
        @Override
        public Object executeInner(Object[] list) throws Exception {
            long[] array = (long[]) list[0];
            return Arrays.stream(array).boxed();
        }
    }

    private static class DoubleArrayStreamOperator extends Operator {
        @Override
        public Object executeInner(Object[] list) throws Exception {
            double[] array = (double[]) list[0];
            return Arrays.stream(array).boxed();
        }
    }

    private static class ByteArrayStreamOperator extends Operator {
        @Override
        public Object executeInner(Object[] list) throws Exception {
            byte[] array = (byte[]) list[0];
            return IntStream.range(0, array.length).mapToObj(e -> array[e]);
        }
    }

    private static class BooleanArrayStreamOperator extends Operator {
        @Override
        public Object executeInner(Object[] list) throws Exception {
            boolean[] array = (boolean[]) list[0];
            return IntStream.range(0, array.length).mapToObj(e -> array[e]);
        }
    }

    private static class ShortArrayStreamOperator extends Operator {
        @Override
        public Object executeInner(Object[] list) throws Exception {
            short[] array = (short[]) list[0];
            return IntStream.range(0, array.length).mapToObj(e -> array[e]);
        }
    }

    private static class CharArrayStreamOperator extends Operator {
        @Override
        public Object executeInner(Object[] list) throws Exception {
            char[] array = (char[]) list[0];
            return IntStream.range(0, array.length).mapToObj(e -> array[e]);
        }
    }

    private static class FloatArrayStreamOperator extends Operator {
        @Override
        public Object executeInner(Object[] list) throws Exception {
            float[] array = (float[]) list[0];
            return IntStream.range(0, array.length).mapToObj(e -> array[e]);
        }
    }

    private ArrayStreamOperatorFactory() {
        // 防止实例化
    }
}